package com.cybertron.ironhide.solr.analysis;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.util.CharArrayMap;
import org.apache.lucene.analysis.util.ResourceLoader;
import org.apache.lucene.analysis.util.ResourceLoaderAware;
import org.apache.lucene.analysis.util.TokenFilterFactory;

public class TagGeneratorFilterFactory extends TokenFilterFactory implements
		ResourceLoaderAware {

	private final boolean ignoreCase;

	private final String wordFiles;

	private final String separator;

	private CharArrayMap<CharArrayMap<String>> words;

	public TagGeneratorFilterFactory(Map<String, String> args) {
		super(args);
		wordFiles = get(args, "words");
		ignoreCase = getBoolean(args, "ignoreCase", false);
		separator = get(args, "split", "=>");
	}

	@Override
	public TokenStream create(TokenStream input) {
		if (words == null) {
			return input;
		} else {
			final TokenStream filter = new TagGeneratorFilter(input, words);
			return filter;
		}
	}

	@Override
	public void inform(ResourceLoader loader) throws IOException {
		if (wordFiles != null) {
			words = getWordMap(loader, wordFiles, ignoreCase);
		}
	}

	public boolean isIgnoreCase() {
		return ignoreCase;
	}

	public CharArrayMap<CharArrayMap<String>> getWords() {
		return words;
	}

	protected final CharArrayMap<CharArrayMap<String>> getWordMap(
			ResourceLoader loader, String wordFiles, boolean ignoreCase)
			throws IOException {
		assureMatchVersion();
		List<String> files = splitFileNames(wordFiles);
		CharArrayMap<CharArrayMap<String>> words = null;
		if (files.size() > 0) {
			words = new CharArrayMap<CharArrayMap<String>>(luceneMatchVersion,
					files.size() * 10, ignoreCase);
			for (String file : files) {
				List<String> wlist = getLines(loader, file.trim());
				makeTagMap(wlist, words, separator);
			}
		}
		return words;
	}

	public void makeTagMap(List<String> wlist,
			CharArrayMap<CharArrayMap<String>> words, String separator) {
		for (String w : wlist) {
			String cateId = StringUtils.substringAfterLast(w, separator);
			CharArrayMap<String> cateMap = words.get(cateId);
			if (cateMap == null) {
				cateMap = new CharArrayMap<String>(luceneMatchVersion, 10,
						ignoreCase);
				words.put(cateId, cateMap);
			}
			String tagId = StringUtils
					.substringBetween(w, separator, separator);
			String val = StringUtils.substringBefore(w, separator);
			cateMap.put(StringUtils.lowerCase(val), tagId);
		}
	}
}
